/*
 * Entry.cpp
 *
 * This source file implements the interfaces declared
 * at the header file: Entry.h
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <iostream>

#include "g_crossbit/Entry.h"
using namespace std;
using namespace g_crossbit;

#define DEBUG

/* Initialize the static members of Entry. */
Entry *Entry::start_entry = NULL;
Entry *Entry::cur_entry = NULL;
int Entry::entry_num = 0;

/*
 * Default constructor.
 */
Entry::Entry () {}

/*
 * Specific constructor.
 *
 * @s_s: Execution point from CPU to GPU.
 * @e_s: Execution point from GPU to CPU.
 */
Entry::Entry (unsigned int s_s, unsigned int e_s)
{
   start_spc = s_s;
   end_spc = e_s;
}

unsigned int
Entry::getStartSpc ()
{
   return start_spc;
}

unsigned int
Entry::getEndSpc ()
{
   return end_spc;
}

/*
 * Load entries from a file. 
 *
 * Parameters:
 * @path_name: absolute or relative path of a file.
 *
 * Return: null
 */
void 
Entry::loadEntries (const char *path_name)
{
   struct stat file_info;

   /*
	* As the file whose absolute or relative path is
	* path_name certainly exists, so each operation
	* on that file will be successful and we don't
	* need to care about the return values of these
	* operations.
	*/
   stat (path_name, &file_info);
   entry_num = (short)(file_info.st_size / sizeof (Entry));

   /* Allocate memory for entries. */
   if ( (start_entry = new Entry[entry_num]) == NULL) {
   	  cout << "There is not enough memory. \n";
	  exit (0);
   }

   int fd = open (path_name, O_RDONLY);
   read (fd, (void *)start_entry, (size_t)file_info.st_size);
   cur_entry = start_entry;
   close (fd);
}

/*
 * display all entries pointed by start_entry.
 */
void
Entry::dumpEntries ()
{
   printf ("start_spc  end_spc\n\n");
   for (int i = 0; i < entry_num; i++) {
   	  printf ("0x%-8x ", start_entry[i].start_spc);
	  printf ("0x%-8x\n" , start_entry[i].end_spc);
   }
}

/*
 * Return the next entry.
 *
 * Parameters: null
 * Returns   : the next entry.
 */
Entry *
Entry::nextEntry ()
{
   cur_entry++;
   if (cur_entry == start_entry + entry_num) 
	  return start_entry;
   else 
	  return cur_entry;
}

/*
 * Free memory allocated for entries.
 *
 * Parameters: null
 * Returns   : null
 */
void
Entry::freeEntries ()
{
   if (start_entry != NULL)
	  delete start_entry;
}
